#pragma once
#include "MallocBase.h"
#include "../Utils/PlatTypeUtil.h"
#include <map>
#include <vector>

struct PtrChunk;

class MallocChest : public MallocBase
{
	friend struct PtrNode;
	friend struct PtrChunk;

	enum
	{
		LARGE_MEMORYPOOL_SIZE = 20 * 1024 * 1024,
		REQUIRED_ALIGNMENT = 16,
		PTRDATA_OVERHEAD = sizeof(PtrData),
		PTRNODE_OVERHEAD = sizeof(PtrNode),
		PTRNODE_ALIGNMENT = 8,

		MAX_NUM_ALLOCS_IN_POOL = 512,

		MEM_TAG = 0xfe,
		MEM_WIPETAG = 0xcd
	};

public:

	MallocChest();

	virtual ~MallocChest();

	virtual void* Malloc(uint32 count, uint32 alignment = DEFAULT_ALIGNMENT) override;


	virtual void* Realloc(void* original, uint32 count, uint32 alignment = DEFAULT_ALIGNMENT) override;


	virtual void Free(void* original) override;

protected:

	bool IsPtrInLarge(uint8* ptr);

protected:

	std::map<uint32, PtrChunk*> mMemoryChunks;

	std::map<uint32, uint32> mAllChunkDesc;

	uint8* mLargePool;

	PtrNode* mLargeHead;

	PtrNode* mLargeTail;
};